home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-02-25 | 12.6 KB | 386 lines | [TEXT/KAHL] |
- //--------------------------------------------------------------------------
- //
- // MyMediaComponentRoutines.c
- // by John Wang
- //
- // Version: 1.0 02/25/93 Based on MyComponent shell.
- //
- //--------------------------------------------------------------------------
-
- //
- // #includes
- //
-
- #include <Components.h>
- #include <Movies.h>
- #include <MediaHandlers.h>
- #include "MyMediaComponent.h"
- #include "MyMediaComponentRoutines.h"
- #include "MyMemory.h"
- #include "QDrawHandler.h"
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaInitialize(PrivateGlobals **storage,
- GetMovieCompleteParams *gmc)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaInitialize()");
-
- // Set characteristics
- (**storage).myMovie = gmc->theMovie;
- (**storage).myTrack = gmc->theTrack;
- (**storage).myMedia = gmc->theMedia;
- (**storage).mediaRate = gmc->effectiveRate;
- SetRect(&((**storage).graphicsBox), 0, 0,
- (short) (gmc->width >> 16), (short) (gmc->height >> 16));
- (**storage).trackMatrix = gmc->trackMovieMatrix;
- (**storage).port = gmc->moviePort;
- (**storage).device = gmc->movieGD;
- (**storage).sampleDescIndex = -1;
-
- // Set MediaIdle globals
- (**storage).somethingChanged = 0xffff;
- (**storage).enabled = FALSE;
- (**storage).newMediaRate = gmc->effectiveRate;
- (**storage).lastMediaTime = -1;
-
- // Return and tell the base media handler our capabilities:
- // 1) handlerHasSpatial: tell handler that we draw.
- // 2) HandlerCanTransferMode: we want to be able to overlap onto another track.
- // 3) handlerNeedsBuffer: we want to use an offscreen buffer so that we don't
- // do compositing on the screen. Remove flag to see the affects of compositing
- // on screen.
- return(MediaSetHandlerCapabilities((**storage).self,
- handlerHasSpatial | handlerCanTransferMode | handlerNeedsBuffer, -1));
- }
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaIdle(PrivateGlobals **storage,
- TimeValue atMediaTime, long flagsIn,
- long *flagsOut, const TimeRecord *movieTime)
- {
- // Media characteristics - preinitialized
- Movie theMovie = (**storage).myMovie;
- Track theTrack = (**storage).myTrack;
- Media theMedia = (**storage).myMedia;
- Fixed theRate = (**storage).mediaRate;
- Rect theGraphicsBox = (**storage).graphicsBox;
- MatrixRecord theTrackMatrix = (**storage).trackMatrix;
- CGrafPtr thePort = (**storage).port;
- GDHandle theGDH = (**storage).device;
- long theSampleIndex = (**storage).sampleDescIndex;
-
- // Media globals - preinitialized
- long theChanged = (**storage).somethingChanged;
- Boolean theEnabled = (**storage).enabled;
- Fixed theNewRate = (**storage).newMediaRate;
- TimeValue theLastMediaTime = (**storage).lastMediaTime;
-
- // MCIdle variables
- OSErr err;
- GDHandle saveGD;
- CGrafPtr savePort;
- Rect myDrawRect;
- Boolean myRedraw;
- Boolean done;
- TimeValue theTime;
-
- // Working sample
- PicHandle myPic;
- long mySize;
- TimeValue mySampleTime;
-
- // Current sample
- PicHandle currPic;
- TimeValue currSampleTime;
- long currSampleIndex;
-
- if (DEBUGME)
- DebugStr("\PIn MyMediaIdle()");
-
- // Initialize by clearing err, saving GWorld, setting to movie GWorld, and creating handles.
- err = noErr;
- myPic = (PicHandle) MyNewHandle(sizeof(Picture));
- currPic = (PicHandle) MyNewHandle(sizeof(Picture));
- if (myPic == nil || currPic == nil) {
- MyDisposeHandle((Handle *) &myPic);
- MyDisposeHandle((Handle *) &currPic);
- return(memFullErr); // Make sure this happens before changing GWorld
- }
- GetGWorld (&savePort, &saveGD);
- SetGWorld ((GWorldPtr) thePort, theGDH);
-
- // Get info about current sample: currPic, currSampleTime, and currSampleIndex
- if ((err = GetMediaSample(theMedia, (Handle) currPic, 0, nil,
- atMediaTime, &currSampleTime, nil, nil, &currSampleIndex, 0, nil, nil))) {
- DebugStr("\PGetMediaSample failed. Do not continue.");
- }
-
- // Check to see if sample desc index changed since the last sample. If the current
- // sample contents have been changed, the our SampleDescChanged routine is called
- if (currSampleIndex != theSampleIndex) {
- theSampleIndex = (**storage).sampleDescIndex = currSampleIndex;
- (**storage).somethingChanged |= kSampleDescChanged;
- }
-
- // If anything in the media changed, we can expect the theChanged boolean to be true.
- // In that case, we need to figure out what has changed and fix things.
- myRedraw = FALSE;
- if (theChanged) {
- // Go through each flag one by one.
- if (theChanged & kSetActive) {
- myRedraw = theEnabled | myRedraw; // If enabled, then start over, else don't change.
- }
- if (theChanged & kSetRate) {
- if ((theRate < 0 && theNewRate > 0) ||
- (theRate > 0 && theNewRate < 0)) {
- myRedraw = TRUE; // If we start playing opposite dir., we start over.
- }
- theRate = (**storage).mediaRate = theNewRate; // Update it!!!
- }
- if (theChanged & kTrackEdited) {
- myRedraw = TRUE; // If edited, then start over.
- }
- if (theChanged & kSetGWorld) {
- myRedraw = TRUE; // If new GWorld, then start over.
- }
- if (theChanged & kSetDimensions) {
- myRedraw = TRUE; // If new dimensions, then start over.
- }
- if (theChanged & kSetMatrix) {
- myRedraw = TRUE; // If new matrix, then start over.
- }
- if (theChanged & kSampleDescChanged) {
- QDrawDescriptionHandle myQDDesc;
-
- if (myQDDesc = (QDrawDescriptionHandle) MyNewHandleClear(sizeof(QDrawDescription))) {
- GetMediaSampleDescription(theMedia, theSampleIndex, (SampleDescriptionHandle) myQDDesc);
- if ((**myQDDesc).version > QDMediaVersion)
- theEnabled = (**storage).enabled = FALSE;
- MyDisposeHandle((Handle *) &myQDDesc);
- } else {
- theEnabled = (**storage).enabled = FALSE;
- }
- }
-
- // Now that everything is updated...
- theChanged = (**storage).somethingChanged = kNoneChanged;
- }
-
- // If we are playing move backwards, then we must always redraw from last sync frame.
- if (theRate < 0)
- myRedraw = TRUE;
-
- // We can now assume that everything is setup correctly. First, the current
- // frame info is in currPic, currSampleTime, and currSampleIndex. And, anything that
- // has changed to the media has been updated.
- // So, now , we have simplified the problem and we have several steps
- // to follow depending on myRedraw.
- // if myRedraw = TRUE: redraw everything since last keyframe
- // if myRedraw = FALSE: redraw everything since last key frame or last media frame,
- // whichever is closer to current frame first.
- // (Drawing is not necessary if myRedraw is false and if theLastMediaTime == currSampleTime
- if (myRedraw || (theLastMediaTime != currSampleTime)) {
- // Let's start by getting last key frame (use nextTimeEdgeOK in case current
- // frame is sync frame) Strangely, if the media doesn't have sync sample, the sample
- // time returned is the same as the same time passed. i.e. every frame is a keyframe.
- GetMediaNextInterestingTime(theMedia, nextTimeSyncSample + nextTimeEdgeOK,
- currSampleTime, -1, &mySampleTime, nil);
-
- // If myRedraw = FALSE, mySampleTime <= theLastMediaTime, and currSampleTime
- // is ahead of theLastMediaTime, then let's search to set the place to draw as the sample
- // after theLastMediaTime.
- // forward to see if we find the theLastMediaTime. If we find it, then set myTime
- // equal to that so that we can begin drawing from there.
- if (!myRedraw && (mySampleTime <= theLastMediaTime) && (theLastMediaTime < currSampleTime)) {
- theTime = mySampleTime;
-
- while (theTime >= 0 && theTime < theLastMediaTime) {
- GetMediaNextInterestingTime(theMedia, nextTimeMediaSample,
- theTime, 1, &theTime, nil);
- }
- if (theTime == theLastMediaTime && theTime != -1) {
- GetMediaNextInterestingTime(theMedia, nextTimeMediaSample,
- theTime, 1, &theTime, nil);
- if (theTime != -1) {
- mySampleTime = theTime;
- } else {
- DebugStr("\PERROR !!!!!");
- }
- }
- }
-
- // Now, we are at the right place to begin drawing. mySampleTime is where we
- // should start drawing. Don't draw if the media is disabled.
- done = FALSE;
- theTime = mySampleTime;
- while (!done && theEnabled) {
- if (theTime == currSampleTime) {
- done = TRUE;
- }
- if ((err = GetMediaSample(theMedia, (Handle) myPic, 0, &mySize,
- theTime, nil, nil, nil, nil, 0, nil, nil))) {
- DebugStr("\PGetMediaSample failed. Do not continue.");
- }
- myDrawRect = (**myPic).picFrame;
- TransformRect(&theTrackMatrix, &myDrawRect, nil);
- DrawPicture(myPic, &myDrawRect);
- if (!done) {
- GetMediaNextInterestingTime(theMedia, nextTimeMediaSample, theTime, 1, &theTime, nil);
- if (theTime < 0) {
- done = TRUE;
- DebugStr("\PERROR!!!!");
- }
- }
- }
-
- // Say we drew somthing.
- *flagsOut |= mDidDraw;
- }
-
- // Update last media time so that we know what the last current sample is.
- (**storage).lastMediaTime = currSampleTime;
-
- // Finishup by restoring GWorld and disposing handles.
- SetGWorld ((GWorldPtr) savePort, saveGD);
- MyDisposeHandle((Handle *) &myPic);
- MyDisposeHandle((Handle *) &currPic);
-
- return(err);
- }
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaSetActive(PrivateGlobals **storage,
- Boolean enableMedia)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaSetActive()");
-
- if ((**storage).enabled != enableMedia) {
- (**storage).enabled = enableMedia;
- (**storage).somethingChanged |= kSetActive;
- }
-
- return(noErr);
- }
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaSetRate(PrivateGlobals **storage,
- Fixed rate)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaSetRate()");
-
- // Save new rate in newMediaRate so that we can compare with previous rate. If the
- // new rate is in the same direction, we won't want to redraw again from keyframe.
- if ((**storage).newMediaRate != rate) {
- (**storage).newMediaRate = rate;
- (**storage).somethingChanged |= kSetRate;
- }
-
- return(noErr);
- }
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaTrackEdited(PrivateGlobals **storage)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaTrackEdited()");
-
- (**storage).somethingChanged |= kTrackEdited;
-
- return(noErr);
- }
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaSetGWorld(PrivateGlobals **storage,
- CGrafPtr aPort, GDHandle aGD)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaSetGWorld()");
-
- // It is possible for the GWorld to not change, but for this call to occur.
- // Therefore, to prevent any unnecessary updates, we don't change anything if
- // both port and gdevice are the same.
- if (((**storage).port != aPort) || ((**storage).device != aGD)) {
- (**storage).port = aPort; // Just to make sure something changed
- (**storage).device = aGD;
- (**storage).somethingChanged |= kSetGWorld;
- }
-
- return(noErr);
- }
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaSetDimensions(PrivateGlobals **storage,
- Fixed width, Fixed height)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaSetDimensions()");
-
- SetRect(&((**storage).graphicsBox), 0, 0,
- (short) (width >> 16), (short) (height >> 16));
- (**storage).somethingChanged |= kSetDimensions;
-
- return(noErr);
- }
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaSetMatrix(PrivateGlobals **storage,
- MatrixRecord *trackMovieMatrix)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaSetMatrix()");
-
- // Let's not cause unnecessary updates if the matrix doesn't really change.
- // This can happen in MoviePlayer if the resize button is clicked on, but not
- // moved.
- if (!EqualMatrix(&((**storage).trackMatrix), trackMovieMatrix)) {
- (**storage).trackMatrix = *trackMovieMatrix;
- (**storage).somethingChanged |= kSetMatrix;
- }
-
- return(noErr);
- }
-
- //--------------------------------------------------------------------------
-
- /*
- pascal ComponentResult MyMediaGetTrackOpaque(PrivateGlobals **storage,
- Boolean *trackIsOpaque)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaGetTrackOpaque()");
-
- // This is toughy. I'm still unsure whether or not this should be true or false.
- *trackIsOpaque = TRUE;
-
- return(noErr);
- }
- */
-
- //--------------------------------------------------------------------------
-
- pascal ComponentResult MyMediaSampleDescriptionChanged(PrivateGlobals **storage,
- long index)
- {
- if (DEBUGME)
- DebugStr("\PIn MyMediaSampleDescriptionChanged()");
-
- // The sample description tables stores info such as data version. This routine is called
- // if the contents of the sample description table changes. It doesn't necessarily
- // get called if the index changes.
- (**storage).sampleDescIndex = index;
- (**storage).somethingChanged |= kSampleDescChanged;
-
- return(noErr);
- }
-